import { _decorator, Component, EventTouch, Node, UITransform, Vec2, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

const tmpVec2 = new Vec2();
const tmpVec3 = new Vec3();
const tmpPos = new Vec3();
const fianlVector=new Vec3();

export enum EJoyStickState {
    START,
    MOVE,
    END,
}
/**
 * 摇杆组件
 */
@ccclass('JoyStick')
export class JoyStick extends Component {
    @property(Node)
    panel: Node;

    @property(Node)
    handle: Node;

    private _transform: UITransform;
    private _isTouching: boolean = false;
    private _maxRadius: number = 0;
    private _onJoyStick: (event: EJoyStickState, direction?: Vec3) => void;
    private _target: any;


    protected onLoad(): void {
        this._transform = this.node.getComponent(UITransform);
        this._maxRadius = Math.pow(this.panel.getComponent(UITransform).contentSize.width / 2, 2);
    }

    public get isTouching(): boolean {
        return this._isTouching;
    }

    public set isTouching(value: boolean) {
        this._isTouching = value;
        this.panel.active = value;
        this.handle.active = value;
    }

    protected onEnable(): void {
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
        // 初始化时隐藏摇杆
        this.isTouching = false;

    }

    protected onDisable(): void {
        this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);

    }

    start() {

    }

    update(deltaTime: number) {

    }

    private onTouchStart(event: EventTouch) {
        this.isTouching = true;
        event.getUIStartLocation(tmpVec2);
        this._transform.convertToNodeSpaceAR(tmpVec3.set(tmpVec2.x, tmpVec2.y), tmpPos);
        this.panel.setPosition(tmpPos);
        this.handle.setPosition(tmpPos);
        this._onJoyStick?.call(this._target, EJoyStickState.START);

    }
    private onTouchMove(event: EventTouch) {
        event.getUILocation(tmpVec2);
        this._transform.convertToNodeSpaceAR(tmpVec3.set(tmpVec2.x, tmpVec2.y), tmpPos);

        let squareDistance = Vec2.squaredDistance(this.panel.position, tmpPos);
        if (squareDistance <= this._maxRadius) {
            this.handle.setPosition(tmpPos);
        } else {
            let rad = Math.atan2(tmpPos.y - this.panel.position.y, tmpPos.x - this.panel.position.x);
            let r = Math.sqrt(this._maxRadius);
            tmpPos.x = this.panel.position.x + Math.cos(rad) * r;
            tmpPos.y = this.panel.position.y + Math.sin(rad) * r;
            this.handle.setPosition(tmpPos);
        }
        fianlVector.set(tmpPos.x-this.panel.position.x,tmpPos.y-this.panel.position.y);
        this._onJoyStick?.call(this._target, EJoyStickState.MOVE, fianlVector.normalize());
    }
    private onTouchEnd(event: EventTouch) {
        this.isTouching = false;
        this._onJoyStick?.call(this._target, EJoyStickState.END);
        
    }
    private onTouchCancel(event: EventTouch) {
        this.isTouching = false;
        this._onJoyStick?.call(this._target, EJoyStickState.END);
    }

    onJoyStick(onJoyStick:(event: EJoyStickState, direction?: Vec3)=>void,target?:any) {
        this._onJoyStick = onJoyStick;
        this._target = target;
        
    }
}


